/**
 * @copyright Copyright (c) 2023..
 *
 * @file    filemanager.h
 * @brief   描述 文件管理模块
 * @author  HC(202206728@any3.com)
 * @version 1.0
 * @date    2023-09-27
 */
#pragma once
#include <map>
#include <vector>
#include <iostream>
#include <iomanip>
#include <queue>

#include "tool.h"

using namespace std;

namespace fileRegion
{
    //先按3种类型文件：视频，中间遍历，图片分；再根据等级（3个）分。共9个文件夹
    enum E_EventLevel
    {
        E_EventLevel_0 = 0x0,    // 包含事件ID 法规约定的目录；暂时保留
        E_EventLevel_1,          // 包含事件ID 
        E_EventLevel_2,          // 包含事件ID 
        E_EventLevel_3,          // 包含事件ID 
        E_EventLevel_err = 0xff, // 无效级别
    };

    enum E_FileType
    {
        FT_CanMiddata = 1,
        FT_VEDIO,
        FT_PICTURE,
    };

    enum E_FolderID
    {
        E_AccidentAndCollision_ID = 0x01,
        E_NonCriticalSecurityLog_ID,
        E_CanMidData_1_ID,
        E_CanMidData_2_ID,
        E_CanMidData_3_ID,
        E_VEDIO_1_ID,
        E_VEDIO_2_ID,
        E_VEDIO_3_ID,
        E_PICTURE_1_ID,
        E_PICTURE_2_ID,
        E_PICTURE_3_ID,
        E_FileTypeErr_ID = 0xff,
    };

    enum E_EventID
    {
        E_EVENT_BA067_ID = 0x06,
        E_EVENT_BA515_ID,
        E_EVENT_BA516_ID,       

    };

    class DataStore
    {
    public:
        DataStore();
        ~DataStore();
        void writeInfoMapToLocal(string fileInfoData);
        // virtual void readLocalGetInfoMap( string fileInfoData ) = 0;
    };

    class FileManager : public DataStore
    {
    public:
        FileManager(/*const std::unique_ptr<DataManagerIF> & dataManager*/);
        ~FileManager();

        // static FileManager *getInstance();
        // void saveFile(vector<uint32_t> &vec_eventid,string filename, uint8_t filetype,uint8_t filelevel);

        //保存文件到指定文件夹路径
        string saveFileToPath(string fileName, string folderPath);

        string cpFileToPath(string fileName, string folderPath);

        //删除指定文件夹下的文件，直到释放指定大小的内存空间
        virtual void delFileFromPath(string folderPath = "", double fileSize = 0.0) = 0;

        //判断指定文件夹是否有足够的空间存储当前文件，有则返回0， 否则返回还需删除的内存空间大小
        double judgeFileToFolder(double fileSize, double folderSize, double folderUseSize, double alarmThreshold, double safetyThreshold);
    };

    class L3FileManager : public FileManager
    {
    public:
        L3FileManager();
        ~L3FileManager();

        static L3FileManager *getInstance();

        // vector<string> split(const string &str, const string &pattern);

        //按照约定文件信息readFileManagerCfg 文件所包含的事件ID、文件类型、文件所在绝对路径、文件优先级
        string saveFile(int level, const string &fileName);

        // void queryFile(string filePath);

        uint8_t getFileLevel(std::vector<int> vecEventid, int *regulAreaFlag);

        uint8_t getFolderId(uint8_t fileLevel, uint8_t fileType);
        uint8_t getFolderId(uint8_t fileLevel);

        string cpFileToRegulArea(string fileName, int regulAreaFlag);

        //删除指定文件夹下的文件，直到释放指定大小的内存空间
        void delFileFromPath(string folderPath = "", double fileSize = 0.0);
        void delFileUploadSuccess(string filePathAndName);

        //读取配置文件
        int readFileManagerCfg();
        void MoveTmpFile();
        void creatPathAndMove();
        void createPath(string folderName);

        void setFileManagerCfgPath(const string &fileManagerCfgPath);
        void calculateMaxSize(string folder);

        //创建指定文件夹，已存在时，则读取本地已保存的文件夹下的文件信息
        void dealFolder(string folderName);

        //获取文件夹下的所有的文件信息
        void getFolderAllFileInfo(string folderPath);
        // void delFileFromPath(string folderpath, uint8_t filerule);

        // void setAdrSystem(adrSystem_component* padrsystemcom);

    private:
        // void init();

    private:
        // key为文件夹名，子map存储文件夹的属性信息，如分配的内存大小、告警阈值、安全阈值、已使用的大小等
        std::map<string, std::map<string, string>> m_folderInfoData;

        // key为文件夹名，子map存储文件夹下的文件信息，以create时间(+文件名)作子map的key,value为文件名 + size
        std::map<string, std::map<string, string>> m_folderAllFileInfo;// levle2  map<0705-14:20-1.txt, 1.txt&1.1M> 

        // std::map<string, std::map<string, string>> m_fileInfoData;

        std::map<uint8_t, string> m_folderIdInfo;
        // std::map<uint32_t, fold_info_stru> m_fileInfoData;

        std::map<string, uint8_t> m_eventLevl;


        std::string m_absolutePath;

        string m_fileManagerCfgPath;

        int m_delTimeRuleFlag;
        int m_delApathyFactorFlag;
    };

}